PCI passthru various Xen changes.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 19 Sep 2007 08:24:20 +0000 (09:24 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Wed, 19 Sep 2007 08:24:20 +0000 (09:24 +0100)
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
Signed-off-by: Guy Zana <guy@neocleus.com>
xen/arch/x86/acpi/boot.c
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
xen/arch/x86/irq.c
xen/arch/x86/setup.c
xen/include/xen/irq.h

index f3ce4119df5f5c7f82dbae9ad37913d94cc1bec1..ba308687acb016cfd19451a45888a62ed4b01a3c 100644 (file)
@@ -1017,5 +1017,7 @@ int __init acpi_boot_init(void)
 
        acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
 
+       acpi_dmar_init();
+
        return 0;
 }
index 0e036cbc17e926df65bf68f037f0d8f88e395278..795c71a7275d021ec3fd859ecdc81a445c7c0336 100644 (file)
@@ -216,11 +216,11 @@ int hvm_domain_initialise(struct domain *d)
     spin_lock_init(&d->arch.hvm_domain.pbuf_lock);
     spin_lock_init(&d->arch.hvm_domain.irq_lock);
 
-    rc = iommu_domain_init(d);
+    rc = paging_enable(d, PG_refcounts|PG_translate|PG_external);
     if ( rc != 0 )
         return rc;
 
-    rc = paging_enable(d, PG_refcounts|PG_translate|PG_external);
+    rc = iommu_domain_init(d);
     if ( rc != 0 )
         return rc;
 
@@ -230,7 +230,11 @@ int hvm_domain_initialise(struct domain *d)
     hvm_init_ioreq_page(d, &d->arch.hvm_domain.ioreq);
     hvm_init_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
 
-    return hvm_funcs.domain_initialise(d);
+    rc = hvm_funcs.domain_initialise(d);
+    if ( rc != 0 )
+        release_devices(d);
+
+    return rc;
 }
 
 void hvm_domain_relinquish_resources(struct domain *d)
@@ -246,6 +250,7 @@ void hvm_domain_relinquish_resources(struct domain *d)
 
 void hvm_domain_destroy(struct domain *d)
 {
+    release_devices(d);
     hvm_funcs.domain_destroy(d);
 }
 
index 75c6afabbeb8d5eb35ee264c6156b5349d0d84af..67175b2f81d9c98e570e6d1f55ef7568a5f36c70 100644 (file)
 #include "msi.h"
 
 #define VTDPREFIX
-static inline int request_irq(int vector, void *func,
-                              int flags, char *name, void *data)
-{
-    return -ENOSYS;
-}
-
 extern void print_iommu_regs(struct acpi_drhd_unit *drhd);
 extern void print_vtd_entries(struct domain *d, int bus, int devfn,
                        unsigned long gmfn);
@@ -1676,7 +1670,7 @@ int iommu_setup(void)
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
 
-    if (list_empty(&acpi_drhd_units))
+    if (!vtd_enabled)
         return 0;
 
     INIT_LIST_HEAD(&hd->pdev_list);
index 8dbaed5957978fc24d429b2ccd8eb77a0fed16fb..b7136157d0f7edde02975800f6301602a8c74642 100644 (file)
@@ -16,6 +16,7 @@
 #include <xen/compat.h>
 #include <asm/current.h>
 #include <asm/smpboot.h>
+#include <asm/iommu.h>
 
 /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */
 int opt_noirqbalance = 0;
@@ -98,6 +99,39 @@ asmlinkage void do_IRQ(struct cpu_user_regs *regs)
     spin_unlock(&desc->lock);
 }
 
+int request_irq(unsigned int irq,
+        void (*handler)(int, void *, struct cpu_user_regs *),
+        unsigned long irqflags, const char * devname, void *dev_id)
+{
+    struct irqaction * action;
+    int retval;
+
+    /*
+     * Sanity-check: shared interrupts must pass in a real dev-ID,
+     * otherwise we'll have trouble later trying to figure out
+     * which interrupt is which (messes up the interrupt freeing
+     * logic etc).
+     */
+    if (irq >= NR_IRQS)
+        return -EINVAL;
+    if (!handler)
+        return -EINVAL;
+
+    action = xmalloc(struct irqaction);
+    if (!action)
+        return -ENOMEM;
+
+    action->handler = handler;
+    action->name = devname;
+    action->dev_id = dev_id;
+
+    retval = setup_irq(irq, action);
+    if (retval)
+        xfree(action);
+
+    return retval;
+}
+
 void free_irq(unsigned int irq)
 {
     unsigned int  vector = irq_to_vector(irq);
@@ -203,7 +237,9 @@ static void __do_IRQ_guest(int vector)
         if ( (action->ack_type != ACKTYPE_NONE) &&
              !test_and_set_bit(irq, d->pirq_mask) )
             action->in_flight++;
-        send_guest_pirq(d, irq);
+        if (!hvm_do_IRQ_dpci(d, irq))
+            send_guest_pirq(d, irq);
+
     }
 }
 
index 94b66e2950718a4350419c551335751cf2560fe5..a4fa6190b9cfed8697a52819ac040f529bce1a1a 100644 (file)
@@ -1038,6 +1038,8 @@ void __init __start_xen(unsigned long mbi_p)
         _initrd_len   = mod[initrdidx].mod_end - mod[initrdidx].mod_start;
     }
 
+    iommu_setup();
+
     /*
      * We're going to setup domain0 using the module(s) that we stashed safely
      * above our heap. The second module, if present, is an initrd ramdisk.
index b92f785b94262666e0e651c7cab125a68643a2f2..392fd2108f1d88ce82c7e7c901a94a09bffe2c8c 100644 (file)
@@ -64,6 +64,9 @@ extern irq_desc_t irq_desc[NR_IRQS];
 
 extern int setup_irq(unsigned int, struct irqaction *);
 extern void free_irq(unsigned int);
+extern int request_irq(unsigned int irq,
+               void (*handler)(int, void *, struct cpu_user_regs *),
+               unsigned long irqflags, const char * devname, void *dev_id);
 
 extern hw_irq_controller no_irq_type;
 extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs);